﻿// -------------------------------------------------------------------------
//    @FileName         :    TestNFShmWithListAdvancedSuite.h
//    @Author           :    gaoyi
//    @Date             :    2024-01-20
//    @Email			:    445267987@qq.com
//    @Module           :    TestNFShmWithListAdvancedSuite
//
// -------------------------------------------------------------------------

#pragma once

/**
 * @file TestNFShmWithListAdvancedSuite.h
 * @brief NFShmWithList系列容器高级链表排序接口的完整测试套件
 * 
 * 本文件整合了所有WithList容器的高级接口测试，包括：
 * 
 * ## 测试的高级接口：
 * 1. **insert_list_sorted()** - 按有序位置插入元素
 * 2. **emplace_list_sorted()** - 原地构造并按有序位置插入
 * 3. **emplace_hint_list_sorted()** - 带提示的原地构造并按有序位置插入
 * 4. **move_to_list_node_front()** - 将节点移到链表前端
 * 5. **move_to_list_node_back()** - 将节点移到链表后端
 * 6. **move_to_list_sorted()** - 将节点移到正确的有序位置
 * 
 * ## 涵盖的容器类型：
 * - **NFShmHashMapWithList** - 唯一键值映射，支持自定义键值比较
 * - **NFShmHashMultiMapWithList** - 多重键值映射，允许相同键的多个值
 * - **NFShmHashSetWithList** - 唯一元素集合，基于元素值排序
 * - **NFShmHashMultiSetWithList** - 多重元素集合，允许重复元素
 * 
 * ## 测试覆盖范围：
 * - 基础功能测试：验证接口的基本功能
 * - 自定义比较器测试：测试用户自定义排序逻辑
 * - 边界情况测试：空容器、单元素、重复元素等
 * - 性能测试：大量数据的插入和移动操作性能
 * - 容器特性测试：各容器类型的特有功能（唯一性、重复性等）
 * - 兼容性测试：与现有接口的兼容性验证
 * 
 * ## 运行说明：
 * 包含此头文件即可运行所有高级接口的测试，每个容器类型的测试相互独立，
 * 可以单独运行也可以作为完整套件运行。
 * 
 * ## 测试数据类型：
 * - 基础类型：int, double, std::string
 * - 复杂对象：UserInfo, ProductInfo, TaskInfo, ExamRecord, RatingRecord
 * - 自定义哈希和比较函数
 * 
 * ## 测试输出：
 * 每个测试都包含详细的printf输出，展示：
 * - 操作前后的数据状态
 * - 排序结果验证
 * - 性能测试结果
 * - 错误情况的诊断信息
 */

// 包含所有高级接口测试
#include "TestNFShmHashMapWithListAdvanced.h"
#include "TestNFShmHashMultiMapWithListAdvanced.h"
#include "TestNFShmHashSetWithListAdvanced.h"
#include "TestNFShmHashMultiSetWithListAdvanced.h"

#include <gtest/gtest.h>
#include <iostream>
#include <chrono>

/**
 * @brief 高级接口测试套件的主测试类
 * 这个测试类提供整体的测试协调和总结功能
 */
class NFShmWithListAdvancedTestSuite : public ::testing::Test
{
protected:
    void SetUp() override
    {
        printf("\n================================================================================\n");
        printf("NFShmWithList系列容器高级接口测试套件开始\n");
        printf("测试涵盖：insert_list_sorted, emplace_list_sorted, emplace_hint_list_sorted\n");
        printf("         move_to_list_node_front, move_to_list_node_back, move_to_list_sorted\n");
        printf("================================================================================\n\n");

        start_time_ = std::chrono::high_resolution_clock::now();
    }

    void TearDown() override
    {
        auto end_time = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time_);

        printf("\n================================================================================\n");
        printf("NFShmWithList系列容器高级接口测试套件完成\n");
        printf("总耗时：%lld 毫秒\n", duration.count());
        printf("================================================================================\n");
    }

private:
    std::chrono::high_resolution_clock::time_point start_time_;
};

/**
 * @brief 验证所有容器类型的高级接口都可用
 */
TEST_F(NFShmWithListAdvancedTestSuite, InterfaceAvailabilityTest)
{
    printf("========== Interface Availability Test ==========\n");
    printf("验证所有WithList容器都实现了高级接口...\n");

    // Map容器接口验证
    {
        NFShmHashMapWithList<int, int, 10> testMap;
        testMap.CreateInit();

        // 验证insert_list_sorted接口
        auto result = testMap.insert_list_sorted({1, 100});
        EXPECT_TRUE(result.second);

        // 验证emplace_list_sorted接口
        auto result2 = testMap.emplace_list_sorted(2, 200);
        EXPECT_TRUE(result2.second);

        // 验证emplace_hint_list_sorted接口
        auto it = testMap.emplace_hint_list_sorted(3, 300);
        EXPECT_EQ(it->first, 3);

        // 验证move接口
        auto find_it = testMap.find(2);
        testMap.move_to_list_node_front(find_it);
        testMap.move_to_list_node_back(find_it);
        testMap.move_to_list_sorted(find_it);

        printf("   NFShmHashMapWithList 高级接口可用\n");
    }

    // MultiMap容器接口验证
    {
        NFShmHashMultiMapWithList<int, int, 10> testMultiMap;
        testMultiMap.CreateInit();

        auto it1 = testMultiMap.insert_list_sorted({1, 100});
        auto it2 = testMultiMap.emplace_list_sorted(2, 200);
        auto it3 = testMultiMap.emplace_hint_list_sorted(3, 300);

        testMultiMap.move_to_list_node_front(it2);
        testMultiMap.move_to_list_node_back(it3);
        testMultiMap.move_to_list_sorted(it1);

        printf("   NFShmHashMultiMapWithList 高级接口可用\n");
    }

    // Set容器接口验证
    {
        NFShmHashSetWithList<int, 10> testSet;
        testSet.CreateInit();

        auto result = testSet.insert_list_sorted(100);
        EXPECT_TRUE(result.second);

        auto result2 = testSet.emplace_list_sorted(200);
        EXPECT_TRUE(result2.second);

        auto it = testSet.emplace_hint_list_sorted(300);
        EXPECT_EQ(*it, 300);

        auto find_it = testSet.find(200);
        testSet.move_to_list_node_front(find_it);
        testSet.move_to_list_node_back(find_it);
        testSet.move_to_list_sorted(find_it);

        printf("   NFShmHashSetWithList 高级接口可用\n");
    }

    // MultiSet容器接口验证
    {
        NFShmHashMultiSetWithList<int, 10> testMultiSet;
        testMultiSet.CreateInit();

        auto it1 = testMultiSet.insert_list_sorted(100);
        auto it2 = testMultiSet.emplace_list_sorted(200);
        auto it3 = testMultiSet.emplace_hint_list_sorted(300);

        testMultiSet.move_to_list_node_front(it2);
        testMultiSet.move_to_list_node_back(it3);
        testMultiSet.move_to_list_sorted(it1);

        printf("   NFShmHashMultiSetWithList 高级接口可用\n");
    }

    printf("所有容器的高级接口验证完成\n");
}

/**
 * @brief 跨容器类型的一致性测试
 */
TEST_F(NFShmWithListAdvancedTestSuite, CrossContainerConsistencyTest)
{
    printf("========== Cross Container Consistency Test ==========\n");
    printf("验证不同容器类型的高级接口行为一致性...\n");

    const std::vector<int> test_data = {50, 30, 70, 20, 60, 40, 80};

    // 测试所有容器使用相同数据的排序一致性
    {
        NFShmHashSetWithList<int, 20> testSet;
        NFShmHashMultiSetWithList<int, 20> testMultiSet;
        testSet.CreateInit();
        testMultiSet.CreateInit();

        // 插入相同数据
        for (int value : test_data)
        {
            testSet.insert_list_sorted(value);
            testMultiSet.insert_list_sorted(value);
        }

        // 验证排序结果一致
        auto set_it = testSet.list_begin();
        auto multiset_it = testMultiSet.list_begin();

        printf("验证Set和MultiSet的排序一致性：\n");
        while (set_it != testSet.list_end() && multiset_it != testMultiSet.list_end())
        {
            printf("  Set: %d, MultiSet: %d\n", *set_it, *multiset_it);
            EXPECT_EQ(*set_it, *multiset_it);
            ++set_it;
            ++multiset_it;
        }

        EXPECT_EQ(testSet.size(), testMultiSet.size());
        printf("   Set和MultiSet排序一致性验证通过\n");
    }

    // 测试Map容器的值排序
    {
        NFShmHashMapWithList<int, int, 20> testMap;
        NFShmHashMultiMapWithList<int, int, 20> testMultiMap;
        testMap.CreateInit();
        testMultiMap.CreateInit();

        // 插入键值对（键和值相同）
        for (int value : test_data)
        {
            testMap.insert_list_sorted({value, value});
            testMultiMap.insert_list_sorted({value, value});
        }

        // 验证值的排序一致性
        auto map_it = testMap.list_begin();
        auto multimap_it = testMultiMap.list_begin();

        printf("验证Map和MultiMap的值排序一致性：\n");
        while (map_it != testMap.list_end() && multimap_it != testMultiMap.list_end())
        {
            printf("  Map: %d->%d, MultiMap: %d->%d\n", map_it->first, map_it->second, multimap_it->first, multimap_it->second);
            EXPECT_EQ(map_it->second, multimap_it->second);
            ++map_it;
            ++multimap_it;
        }

        printf("   Map和MultiMap值排序一致性验证通过\n");
    }

    printf("跨容器一致性测试完成\n");
}

/**
 * @brief 综合性能对比测试
 */
TEST_F(NFShmWithListAdvancedTestSuite, ComprehensivePerformanceTest)
{
    printf("========== Comprehensive Performance Test ==========\n");
    printf("对比不同容器类型的高级接口性能...\n");

    const int TEST_SIZE = 500;

    // 准备测试数据
    std::vector<int> test_data;
    for (int i = 1; i <= TEST_SIZE; ++i)
    {
        test_data.push_back(i);
    }

    std::random_device rd;
    std::mt19937 gen(rd());
    std::shuffle(test_data.begin(), test_data.end(), gen);

    struct PerformanceResult
    {
        std::string container_type;
        long long insert_time_us;
        long long move_time_us;
        size_t final_size;
    };

    std::vector<PerformanceResult> results;

    // 测试Map容器性能
    {
        NFShmHashMapWithList<int, int, TEST_SIZE> perfMap;
        perfMap.CreateInit();

        auto start = std::chrono::high_resolution_clock::now();
        for (int value : test_data)
        {
            perfMap.insert_list_sorted({value, value});
        }
        auto end = std::chrono::high_resolution_clock::now();
        auto insert_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < 50; ++i)
        {
            auto it = perfMap.find(i + 1);
            if (it != perfMap.end())
            {
                perfMap.move_to_list_sorted(it);
            }
        }
        end = std::chrono::high_resolution_clock::now();
        auto move_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        results.push_back({"NFShmHashMapWithList", insert_time.count(), move_time.count(), perfMap.size()});
    }

    // 测试Set容器性能
    {
        NFShmHashSetWithList<int, TEST_SIZE> perfSet;
        perfSet.CreateInit();

        auto start = std::chrono::high_resolution_clock::now();
        for (int value : test_data)
        {
            perfSet.insert_list_sorted(value);
        }
        auto end = std::chrono::high_resolution_clock::now();
        auto insert_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < 50; ++i)
        {
            auto it = perfSet.find(i + 1);
            if (it != perfSet.end())
            {
                perfSet.move_to_list_sorted(it);
            }
        }
        end = std::chrono::high_resolution_clock::now();
        auto move_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        results.push_back({"NFShmHashSetWithList", insert_time.count(), move_time.count(), perfSet.size()});
    }

    // 输出性能对比结果
    printf("\n性能测试结果 (测试数据量: %d):\n", TEST_SIZE);
    printf("%-25s | %15s | %15s | %10s\n", "容器类型", "插入时间(μs)", "移动时间(μs)", "最终大小");
    printf("-------------------------+----------------+----------------+-----------\n");

    for (const auto& result : results)
    {
        printf("%-25s | %15lld | %15lld | %10zu\n", result.container_type.c_str(), result.insert_time_us, result.move_time_us, result.final_size);
    }

    printf("\n性能测试完成\n");
}

/**
 * @brief 错误处理和边界情况测试
 */
TEST_F(NFShmWithListAdvancedTestSuite, ErrorHandlingAndEdgeCasesTest)
{
    printf("========== Error Handling and Edge Cases Test ==========\n");
    printf("测试错误处理和边界情况...\n");

    // 测试空容器
    {
        printf("测试空容器的高级接口调用：\n");

        NFShmHashMapWithList<int, int, 10> emptyMap;
        emptyMap.CreateInit();
        EXPECT_EQ(emptyMap.size(), 0);

        auto result = emptyMap.insert_list_sorted({1, 100});
        EXPECT_TRUE(result.second);
        EXPECT_EQ(emptyMap.size(), 1);
        printf("   空Map容器插入成功\n");

        NFShmHashSetWithList<int, 10> emptySet;
        emptySet.CreateInit();
        auto result2 = emptySet.insert_list_sorted(100);
        EXPECT_TRUE(result2.second);
        printf("   空Set容器插入成功\n");
    }

    // 测试满容器的LRU行为
    {
        printf("测试满容器的LRU行为：\n");

        const int SMALL_SIZE = 5;
        NFShmHashMapWithList<int, int, SMALL_SIZE> smallMap;
        smallMap.CreateInit();
        smallMap.enable_lru();

        // 填满容器
        for (int i = 1; i <= SMALL_SIZE; ++i)
        {
            smallMap.insert_list_sorted({i, i * 10});
        }
        EXPECT_EQ(smallMap.size(), SMALL_SIZE);
        EXPECT_TRUE(smallMap.full());

        // 再插入应该触发LRU淘汰
        smallMap.insert_list_sorted({6, 60});
        EXPECT_EQ(smallMap.size(), SMALL_SIZE); // 大小不变
        EXPECT_TRUE(smallMap.full());

        printf("   LRU淘汰机制正常工作\n");
    }

    // 测试重复元素处理
    {
        printf("测试重复元素处理：\n");

        NFShmHashSetWithList<int, 10> uniqueSet;
        uniqueSet.CreateInit();

        auto result1 = uniqueSet.insert_list_sorted(100);
        EXPECT_TRUE(result1.second);

        auto result2 = uniqueSet.insert_list_sorted(100); // 重复
        EXPECT_FALSE(result2.second);
        EXPECT_EQ(uniqueSet.size(), 1);
        printf("   Set容器正确拒绝重复元素\n");

        NFShmHashMultiSetWithList<int, 10> multiSet;
        multiSet.CreateInit();

        multiSet.insert_list_sorted(100);
        multiSet.insert_list_sorted(100); // 允许重复
        EXPECT_EQ(multiSet.size(), 2);
        EXPECT_EQ(multiSet.count(100), 2);
        printf("   MultiSet容器正确接受重复元素\n");
    }

    printf("错误处理和边界情况测试完成\n");
}
